<template>
  <div class="draw-circle"  @touchstart="touch" @touchmove="touch" @touchend="touch">
    <div class="circle"></div>
    <div class="canvas" ref="canvas"></div>
  </div>
</template>
<script lang="ts">
import { Vue,  Options, Emit } from 'vue-property-decorator';
import * as THREE from 'three';
import Particle from '../libs/Particle';
const renderer = new THREE.WebGLRenderer({
  alpha: true,
  premultipliedAlpha: true,
});
renderer.debug.checkShaderErrors = false;
renderer.setClearColor(new THREE.Color(), 0);
const scene = new THREE.Scene();
const particle = new Particle({
  count: 32 ** 2,
  emit_random: 5,
  lifetime: 1.5,
  lifetime_random: 1,
  lifetime_count: 0,
  size: 12,
  // size_random: 1,
  velocity: {
    factor_random: 0,
  },
  forces: {
    gravity: 0,
    turbulence: 20,
    damping: .01,
  },
});
scene.add(particle);
// 正交摄像机
const camera = new THREE.OrthographicCamera();
camera.near = -750;
camera.far = 750;
@Options({ components: {} })
export default class DrawCircle extends Vue {
  public rect: DOMRect|null=null;
  public ctx: CanvasRenderingContext2D|null=null;
  public touchScale = 1;
  public dpr = 750 / window.innerWidth;
  public touchState = 0;
  // 0 未按下按键的状态
  // -1 按下按键且按下的位置不在可绘制区域内的状态
  // 1 按下按键且按下的位置在可绘制区域内的状态
  public touchPath = [0, 0, 0, 0, 0, 0, 0, 0];
  public touchPos = { x: 0, y: 0 };

  public touch(e: TouchEvent) {
    switch (e.type) {
      case 'touchstart': {
      }
      case 'touchmove': {
        const touchX = e.touches[0].pageX * this.touchScale - this.rect!.width / 2;
        const touchY = e.touches[0].pageY * this.touchScale - this.rect!.height / 2;
        const radius = Math.hypot(touchX, touchY) / window.autoScale;
        if (radius < this.rect!.width / 1.8 && radius >  this.rect!.width / 5) {
          // 在可绘制区域内
          // 按键按下且上一次在可绘制区域或者上一次没有按下按键
          if (this.touchState !== -1) {
            this.touchState = 1;
            this.touchPos.x = touchX;
            this.touchPos.y = touchY;
            const progress = (Math.atan2(touchX, touchY) + Math.PI) / (Math.PI * 2);
            this.touchPath[Math.round(progress * 7)] = 1;
            if (particle.particleInfo.lifetime_count === 0) {
              particle.position.x = this.touchPos.x;
              particle.position.y = this.touchPos.y;
              particle.run(-1);
            }
          } else {
            // 按键按下且上一次不在可绘制区域
          }
        } else {
          // 不在可绘制区域内
          particle.run(0);
          // 如果关键点都绘制完成 跳转到下一页
          if (!this.touchPath.includes(0)) {
            this.next();
          }
          // 移动到不可绘制区域时 如果关键点没有绘制完成 取消所有关键点的赋值置空
          this.touchPath = [0, 0, 0, 0, 0, 0, 0, 0];
          if (this.touchState === 1) {
            // 按键按下且上一次在可绘制区域  将状态置为不在绘制区域的状态
            this.touchState = -1;
          }
        }
        break;
      }
      case 'touchend': {
        particle.run(0);
        // 状态置为按键未按下
        this.touchState = 0;
        // 用户绘制圆的路径完整 全部都不是0
        if (!this.touchPath.includes(0)) {
          this.next();
        }
        this.touchPath =  [0, 0, 0, 0, 0, 0, 0, 0];
      }
    }
  }
  @Emit() private next() {}
  public mounted() {
    this.rect = (this.$el as HTMLElement).getBoundingClientRect();
    (this.$refs.canvas as HTMLDivElement).append(renderer.domElement);
    this.touchScale = this.rect!.width / window.innerWidth;
    // 设置设备像素比 避免绘图模糊
    renderer.setPixelRatio(this.dpr);
    // 调整输出canvas的大小 false阻止对canvas的样式做改变
    renderer.setSize(this.rect.width, this.rect.height, false);
    // ？？？？
    camera.left = -this.rect.width / 2;
    camera.right = this.rect.width / 2;
    camera.top = -this.rect.height / 2;
    camera.bottom = this.rect.height / 2;
    // 大多数属性发生改变之后，你将需要调用.updateProjectionMatrix来使得这些改变生效。
    camera.updateProjectionMatrix();
    renderer.setAnimationLoop(() => {
      // 回调函数 每个可用帧都会调用的参数
      const offsetPosition = new THREE.Vector3(
        this.touchPos.x - particle.position.x,
        this.touchPos.y - particle.position.y,
        0.001,
      );
      particle.position.x += offsetPosition.x;
      particle.position.y += offsetPosition.y;
      // normalize将该向量转换为单位向量  multiplyScalar(s)将该向量与所传入的标量s进行相乘。
      offsetPosition.normalize().multiplyScalar(30);
      // ???
      particle.particleInfo.velocity?.object_factor?.copy(offsetPosition);
      renderer.render(scene, camera);
    });
  }
  public unmounted() {
    // 传入‘null’,所有正在进行的动画都会停止
    renderer.setAnimationLoop(null);
  }
}
</script>
<style scoped lang="postcss">
.draw-circle{
  touch-action: none;
  position: absolute;
  left: 0%;top: 0%;
  width: 100%;height: 100%;
  .circle{
    position: absolute;
    left: 50%;top: 50%;
    background: url(../assets/circle.png#s.5);
    background-image: none;
    transform:rotateZ(-360deg);
    animation: rotateAni 10s linear infinite;
    &::before{
      content:'';
      position: absolute;
      left: 3%;top: 3%;
      width: 94%;height: 94%;
      border:1px dotted #13FFFF;
      border-radius: 50%;
    }
    &::after{
      content: '';
      position: absolute;
      top: 1.5%;left: 50%;
      width: 0;height: 0;
      border-left:7px solid #13ffff;
      border-top:5px solid transparent;
      border-bottom:5px solid transparent;
    }
  }
}
@keyframes rotateAni {
  100%{
    transform: none;
    opacity: 1;
  }
}
</style>
